using System;

namespace SharpMud.MudLib.SAMPLE.Environment
{
	[AttributeUsage(System.AttributeTargets.Field)]
	public class ReverseExitDirectionAttribute : System.Attribute
	{
		#region Instance Stuff
		#region Private Variables
		private ExitDirection _ReverseDirection;
		#endregion

		#region Constructors
		private ReverseExitDirectionAttribute()
		{
		}
		public ReverseExitDirectionAttribute(ExitDirection reverseDirection)
		{
			_ReverseDirection = reverseDirection;
		}
		#endregion

		#region Public Properties
		public ExitDirection ReverseDirection
		{
			get
			{
				return _ReverseDirection;
			}
		}
		#endregion
		#endregion

		#region Static Stuff
		private static ExitDirection[,] _ReverseDirectionChart;
		static ReverseExitDirectionAttribute()
		{
			InitStatic();
		}
		private static void InitStatic()
		{
			ExitDirection[] EDs = (ExitDirection[])System.Enum.GetValues(typeof(ExitDirection));
			_ReverseDirectionChart = new ExitDirection[2,EDs.Length];
			for(int x=0;x<EDs.Length;x++)
			{
				_ReverseDirectionChart[0,x] = EDs[x];
				_ReverseDirectionChart[1,x] = FindReverseExitDirection(EDs[x]);
			}
		}

		/// <summary>
		/// Looks for the reverse exit direction for the given exit direction
		/// </summary>
		/// <param name="exitDirection">The direction for which the reverse is being asked</param>
		/// <returns>Returns an exit direction - the reverse direction of the one given</returns>
		private static ExitDirection FindReverseExitDirection(ExitDirection exitDirection)
		{
			System.Reflection.FieldInfo fi = typeof(ExitDirection).GetField(exitDirection.ToString());
			ReverseExitDirectionAttribute[] reda = (ReverseExitDirectionAttribute[])fi.GetCustomAttributes(typeof(ReverseExitDirectionAttribute),true);
			foreach(ReverseExitDirectionAttribute r in reda)
			{
				return r.ReverseDirection;
			}
			throw new InvalidOperationException("The reverse exit direction could not be determined.");
		}

		/// <summary>
		/// Determines the reverse exit direction for the given exit direction
		/// </summary>
		/// <param name="exitDirection">The direction for which the reverse is being asked</param>
		/// <returns>Returns an exit direction - the reverse direction of the one given</returns>
		public static ExitDirection GetReverseExitDirection(ExitDirection exitDirection)
		{
			if(_ReverseDirectionChart==null)
				InitStatic();
			for(int x=0;x<_ReverseDirectionChart.Length;x++)
			{
				if(_ReverseDirectionChart[0,x]==exitDirection)
					return _ReverseDirectionChart[1,x];
			}
			return FindReverseExitDirection(exitDirection);
		}
		#endregion
	}
}